import 'package:get/get.dart';
import 'package:mmkv/mmkv.dart';
import 'package:myapp/app/data/entities/article_item.dart';
import 'package:myapp/app/data/entities/banner_model.dart';
import 'package:myapp/app/data/entities/bw_realtor_model.dart';
import 'package:myapp/app/data/entities/movie_model.dart';
import 'package:myapp/app/data/entities/net_response.dart';
import 'package:myapp/app/data/entities/user_model.dart';
import 'package:myapp/app/utils/main_const.dart';

class ApiProvider extends GetConnect {

  static const String _TOKEN = MainConst.MMKV_TOKEN;

  late MMKV _mmkv;
  @override
  void onInit() {
    _mmkv = MMKV.defaultMMKV();
    httpClient.baseUrl = 'https://www.fastmock.site/mock/93578d086bffef256750a9ca50eb99eb/cli/';
    httpClient.defaultContentType = "application/json";
    httpClient.addRequestModifier<void>((request) {
      request.headers['blade-auth'] = _mmkv.decodeString(_TOKEN)??"";
      return request;
    });

    httpClient.addResponseModifier<void>((request, response) {
      print("request url ${request.url}::${request.method}");
      print("request headers ${request.headers}\n");
      print("response: ${response.bodyString}\n");
    });
  }

  _check(Response<NetResponse<dynamic>> response) {
    if (!(response.body?.success ?? false)) {
      throw response.body?.message??"网络异常";
    }
  }

  _checkList(Response<NetListResponse<dynamic>> response) {
    if (!(response.body?.success ?? false)) {
      throw response.body?.message??"网络异常";
    }
  }

  Future<BwRealtor> getBwRealtor() async {
    var response = await get("api/BwRealtor/get",
        decoder: (data) => NetResponse<Map<String, dynamic>>.fromJson(data));
    _check(response);
    return BwRealtor.fromJson(response.body?.data?? {});
  }

  Future<User> login(String userName, String password) async {
    var mapData = {};
    mapData['username'] = userName;
    mapData['password'] = password;
    var response = await post("login", mapData, decoder: (data)=> NetResponse<Map<String, dynamic>>.fromJson(data));
    _check(response);
    return User.fromJson(response.body!.data!);
  }

  Future<User> tokenLogin() async {
    var response = await get("tokenLogin", decoder: (data)=> NetResponse<Map<String, dynamic>>.fromJson(data));
    _check(response);
    return User.fromJson(response.body!.data!);
  }

  Future<String> deviceRegister(String deviceName, String deviceId, String deviceVersion) async {
    var requestMap = {};
    requestMap['deviceName'] = deviceName;
    requestMap['deviceId'] = deviceId;
    requestMap['deviceVersion'] = deviceVersion;
    var response = await post("deviceRegister", requestMap, decoder: (data) => NetResponse<Map<String, dynamic>>.fromJson(data));
    _check(response);
    return response.body!.data!['token'];
  }

  Future<List<ArticleItem>> getArticleList() async {
    final response = await get("articleList", decoder: (data) => NetListResponse<Map<String, dynamic>>.fromJson(data));
    _checkList(response);
    return response.body!.data!.map(_toArticle).toList();
  }

  ArticleItem _toArticle(Map<String, dynamic> json) {
    final int type = json['type'];
    if(type == 2) {
      return ImageArticleItem.fromJson(json);
    } else if(type == 3) {
      return MultipleImageArticleItem.fromJson(json);
    } else {
      return TextArticleItem.fromJson(json);
    }
  }

  Future<List<Banner>> getBannerList() async {
    final response = await get("getBanner", decoder: (data)=> NetListResponse<Map<String, dynamic>>.fromJson(data));
    _checkList(response);
    return response.body!.data!.map((e) => Banner.fromJson(e)).toList();
  }

  //todo 自己序列号对象很麻烦，特别是复杂对象
  Map<String, List<Movie>> _mm(Map<String, dynamic> params) {
    final map = <String, List<Movie>>{};
    final list = <Movie>[];
    var val = params.values.first as List<dynamic>;
    list.addAll(val.map((e) => Movie.fromJson(e as Map<String, dynamic>)).toList());
    var keys = params.keys.first;
    map[keys] = list;
    return map;
  }

  Future<List<Map<String, List<Movie>>>> getMovies() async {
    final response = await get("getMovies", decoder: (data)=> NetListResponse<Map<String, dynamic>>.fromJson(data));
    _checkList(response);
    return response.body!.data!.map((e) => _mm(e)).toList();
  }
}
